import { nextTick } from 'vue';
import { GlFormGroup, GlFormInput, GlFormTextarea } from '@gitlab/ui';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
import SectionName from 'ee/vulnerabilities/components/new_vulnerability/section_name.vue';
import { ERROR_NAME } from 'ee/vulnerabilities/components/new_vulnerability/i18n';

describe('New vulnerability - Section Name', () => {
  const markdownDocsPath = '/path/to/markdown/docs';
  const markdownPreviewPath = '/path/to/markdown/preview';

  let wrapper;

  const findFormGroup = (index) => wrapper.findAllComponents(GlFormGroup).at(index);

  const createWrapper = () => {
    return mountExtended(SectionName, {
      provide: {
        markdownDocsPath,
        markdownPreviewPath,
      },
    });
  };

  beforeEach(() => {
    wrapper = createWrapper();
  });

  it('creates markdown editor with correct props', () => {
    expect(wrapper.findComponent(MarkdownField).props()).toMatchObject({
      markdownDocsPath,
      markdownPreviewPath,
      textareaValue: '',
      canAttachFile: false,
      addSpacingClasses: false,
      isSubmitting: false,
      restrictedToolBarItems: ['attach-file'],
    });
  });

  it.each`
    labelText        | description
    ${'Name'}        | ${'Vulnerability name or type. Ex: Cross-site scripting'}
    ${'Description'} | ${''}
  `('displays the input with the correct label: $labelText', ({ labelText, description }) => {
    expect(wrapper.findByLabelText(labelText).exists()).toBe(true);

    if (description) {
      expect(wrapper.findByText(description).exists()).toBe(true);
    }
  });

  it.each`
    field            | component         | fieldKey               | fieldValue
    ${'Name'}        | ${GlFormInput}    | ${'vulnerabilityName'} | ${'CVE 2021'}
    ${'Description'} | ${GlFormTextarea} | ${'vulnerabilityDesc'} | ${'Password leak'}
  `('emits the changes: $field', ({ component, fieldKey, fieldValue }) => {
    wrapper.findComponent(component).setValue(fieldValue);
    wrapper.findComponent(component).vm.$emit('change', fieldValue);
    expect(wrapper.emitted('change')[0][0]).toEqual({
      vulnerabilityName: '',
      vulnerabilityDesc: '',
      [fieldKey]: fieldValue,
    });
  });

  it('does not display invalid state by default', () => {
    expect(findFormGroup(0).attributes('aria-invalid')).toBeUndefined();
  });

  it('handles form validation', async () => {
    wrapper.setProps({
      validationState: {
        name: false,
      },
    });

    await nextTick();

    expect(findFormGroup(0).attributes('aria-invalid')).toBe('true');
    expect(findFormGroup(0).text()).toContain(ERROR_NAME);
  });
});
